/*
 * multi_thread_socket_server.c
 *
 *  Created on: Mar 14, 2014
 *      Author: nerohwang
 */
#include "time.h"
#include<stdlib.h>
#include<pthread.h>
#include<sys/socket.h>
#include<sys/types.h>       //pthread_t , pthread_attr_t and so on.
#include<stdio.h>
#include<netinet/in.h>      //structure sockaddr_in
#include<arpa/inet.h>       //Func : htonl; htons; ntohl; ntohs
#include<assert.h>          //Func :assert
#include<string.h>          //Func :memset
#include<unistd.h>          //Func :close,write,read
#define SOCK_PORT 13227
#define BUFFER_LENGTH 1024
#define MAX_CONN_LIMIT 512     //MAX connection limit
struct sockaddr_in s_addr_client;
itoa(int n,char str[64]);
static void Data_handle(void * sock_fd);   //Only can be seen in the file

int main()
{
    int sockfd_server;
    int sockfd;
    int fd_temp;
    struct sockaddr_in s_addr_in;   
    int client_length;
	int a=0;
    sockfd_server = socket(AF_INET,SOCK_STREAM,0);  //ipv4,TCP
    assert(sockfd_server != -1);

    //before bind(), set the attr of structure sockaddr.
    memset(&s_addr_in,0,sizeof(s_addr_in));
    s_addr_in.sin_family = AF_INET;
    s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);  //trans addr from uint32_t host byte order to network byte order.
    s_addr_in.sin_port = htons(SOCK_PORT);          //trans port from uint16_t host byte order to network byte order.
    fd_temp = bind(sockfd_server,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));
    if(fd_temp == -1)
    {
        fprintf(stderr,"bind error!\n");
        exit(1);
    }

    fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
    if(fd_temp == -1)
    {
        fprintf(stderr,"listen error!\n");
        exit(1);
    }

    while(1)
    {	
	printf("process:%d\n",a++);
        printf("waiting for new connection...\n");
        pthread_t thread_id;
        client_length = sizeof(s_addr_client);

        //Block here. Until server accpets a new connection.
        sockfd = accept(sockfd_server,(struct sockaddr *)(&s_addr_client),(socklen_t *)(&client_length));
        if(sockfd == -1)
        {
            fprintf(stderr,"Accept error!\n");
            continue;                               //ignore current socket ,continue while loop.
        }
        printf("A new connection occurs!\n");
        pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd));
	pthread_join(thread_id,NULL);
    }

    //Clear
    int ret = shutdown(sockfd_server,SHUT_WR); //shut down the all or part of a full-duplex connection.
    assert(ret != -1);

    printf("Server shuts down\n");
    return 0;
}

static void Data_handle(void * sock_fd)
{
    int fd = *((int *)sock_fd);
    int i_recvBytes;
    int i,count=0;
    char buffer[1024];
    char data_send[64]="hello";

	
     //char * data_send = "Server has received your request!\n";
	//strcat(data_send,inet_ntoa(s_addr_client.sin_addr));
//	puts(s_addr_client.sin_addr)
	//strcat(data_send,"\n20155222\n");
 while(1)
    {
        printf("waiting for request...\n");
        //Reset data.
        //memset(data_recv,0,BUFFER_LENGTH);
	// write(fd,data_send,strlen(data_send));
        while((i_recvBytes = read(fd,buffer,1024))>0)
        {
             	//count=0;
		int flag = 0;
	//	printf("%d\n",i_recvBytes);
	//	printf("%s\n",buffer);
		for(i=0;i<i_recvBytes;i++)
		{
			if(flag==0){
			switch(buffer[i]){
			case ' ':
				count++;
				break;
			case '\n':
				count++;
				break;
			case '\r':
				count++;
				break;
			}
			}
			if(buffer[i]==' '||buffer[i]=='\n'||buffer[i]=='\r')flag=1;
			else flag=0;
		}
		/*
		for(i=0;i<i_recvBytes;i++)
		if((buffer[i]==' '||buffer[i]==10)&&((buffer[i-1]>='A'&&buffer[i-1]<='Z')||(buffer[i-1]>='a'&&buffer[i-1]<='z')))
              	{
			count++;
			break;
		}
		i--;
		  for(;i<i_recvBytes;i++)
                if((buffer[i]==' '||buffer[i]=='('||buffer[i]=='\t'||buffer[i]=='\r')&&((buffer[i+1]>='A'&&buffer[i+1]<='Z')||(buffer[i+1]>='a'&&buffer[i+1]<='z')))
                */
		//for(i=0;i<i_recvBytes;i++)
		//if(buffer[i]==' '||buffer[i]=='\n'||buffer[i]=='\t')
	//	count++;
		bzero(buffer,1024);
		//printf("%d\n",count);
        }
        //printf("fffaff\n");

	write(fd,data_send,strlen(data_send));
        /*while((i_recvBytes = read(fd,buffer,1024))>0)
	{
	//	puts(buffer);
		for(i=0;i<i_recvBytes;i++)
		if(buffer[i]!=' '&&buffer[i]!='\n')
		count++;
	}
	printf("a");*/
        /*if(i_recvBytes == 0)
        {
            printf("Maybe the client has closed\n");
            break;
        }
        if(i_recvBytes == -1)
        {
            fprintf(stderr,"read error!\n");
            break;
        }
        if(strcmp(data_recv,"quit")==0)
        {
            printf("Quit command!\n");
            break;                           //Break the while loop.
        }*/
       // printf("read from client : %s\n",data_recv);
	//printf("%d",count);
	bzero(data_send,64);
	itoa(count,data_send);
	puts(data_send);
        if(write(fd,data_send,strlen(data_send)+1) == -1)
        {
           printf("send failure"); 
	   break;
        }
	time_t timep;
   	time (&timep);
   	break;
	/*if(write(fd,ctime(&timep),strlen(ctime(&timep))) == -1)
        {
            break;
        }*/
	
    }

    //Clear
    printf("terminating current client_connection...\n");
    close(fd);            //close a file descriptor.
    pthread_exit(NULL);   //terminate calling thread!
}
itoa(int n,char str[64])
{
        int i=0,len;
        char temp;
        
        while(n>10)
        {
                str[i]=n%10+48;
    //            printf("%d,%c\n",n,str[i]);
                n/=10;
                i++;
        }

        str[i]=n+48;
        
        len=strlen(str);
        for(i=0;i<len/2;i++)
        {
                temp=str[i];
                str[i]=str[len-i-1];
                str[len-i-1]=temp;
        }
}

